#include "database/command_repository.h"
#include <QDebug>
#include <QDir>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>

CommandRepository::CommandRepository(QSqlDatabase &database)
    : m_database(database)
{
}

bool CommandRepository::isDatabaseConnected() const
{
    return m_database.isOpen() && m_database.isValid();
}

KmsCommand CommandRepository::mapFromQuery(const QSqlQuery &query) const
{
    KmsCommand command;
    command.id = query.value("ID").toString();
    command.command = query.value("COMMAND").toString();
    command.params = query.value("PARAMS").toString();
    command.createDate = query.value("CREATE_DATE").toString();
    command.lastModifyDate = query.value("LAST_MODIFY_DATE").toString();
    command.status = query.value("STATUS").toString();
    return command;
}

// 从 PARAMS JSON 中解析出参数值
QString CommandRepository::getParamFromJson(const QString &paramsJson, const QString &key) const
{
    if (paramsJson.isEmpty()) {
        return QString();
    }
    
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(paramsJson.toUtf8(), &parseError);
    
    if (parseError.error != QJsonParseError::NoError || !jsonDoc.isObject()) {
        qDebug() << "解析 PARAMS JSON 失败:" << parseError.errorString();
        return QString();
    }
    
    QJsonObject paramsObj = jsonDoc.object();
    return paramsObj.value(key).toString();
}

// 构建 PARAMS JSON 字符串
QString CommandRepository::buildParamsJson(const QString &localFilePath, const QString &downloadUrl, 
                                           const QString &commitUrl, const QString &accessToken) const
{
    QJsonObject paramsObj;
    if (!localFilePath.isEmpty()) {
        paramsObj["LOCAL_FILE_PATH"] = localFilePath;
    }
    if (!downloadUrl.isEmpty()) {
        paramsObj["DOWNLOAD_URL"] = downloadUrl;
    }
    if (!commitUrl.isEmpty()) {
        paramsObj["COMMIT_URL"] = commitUrl;
    }
    if (!accessToken.isEmpty()) {
        paramsObj["ACCESS_TOKEN"] = accessToken;
    }
    
    QJsonDocument jsonDoc(paramsObj);
    return jsonDoc.toJson(QJsonDocument::Compact);
}

// 更新 PARAMS JSON 中的某个字段
QString CommandRepository::updateParamInJson(const QString &paramsJson, const QString &key, const QString &value) const
{
    QJsonObject paramsObj;
    
    // 如果已有 JSON，先解析
    if (!paramsJson.isEmpty()) {
        QJsonParseError parseError;
        QJsonDocument jsonDoc = QJsonDocument::fromJson(paramsJson.toUtf8(), &parseError);
        if (parseError.error == QJsonParseError::NoError && jsonDoc.isObject()) {
            paramsObj = jsonDoc.object();
        }
    }
    
    // 更新或添加字段
    if (!value.isEmpty()) {
        paramsObj[key] = value;
    } else {
        paramsObj.remove(key);
    }
    
    QJsonDocument jsonDoc(paramsObj);
    return jsonDoc.toJson(QJsonDocument::Compact);
}

bool CommandRepository::insert(const KmsCommand &command)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("INSERT INTO kms_command (ID, COMMAND, PARAMS, CREATE_DATE, LAST_MODIFY_DATE, STATUS) "
                  "VALUES (?, ?, ?, ?, ?, ?)");
    
    query.addBindValue(command.id);
    query.addBindValue(command.command);
    query.addBindValue(command.params);
    query.addBindValue(command.createDate);
    query.addBindValue(command.lastModifyDate);
    query.addBindValue(command.status);
    
    if (!query.exec()) {
        qDebug() << "插入命令记录失败:" << query.lastError().text();
        return false;
    }
    
    qDebug() << "成功插入命令记录，ID:" << command.id << "命令:" << command.command;
    return true;
}

bool CommandRepository::updateLocalFilePath(const QString &downloadUrl, const QString &localFilePath)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    if (downloadUrl.isEmpty()) {
        qDebug() << "下载URL为空，无法更新命令记录";
        return false;
    }
    
    // 先查找匹配的记录
    QSqlQuery findQuery(m_database);
    findQuery.prepare("SELECT * FROM kms_command WHERE PARAMS LIKE ?");
    findQuery.addBindValue("%\"DOWNLOAD_URL\":\"" + downloadUrl + "\"%");
    
    if (!findQuery.exec()) {
        qDebug() << "查询命令记录失败:" << findQuery.lastError().text();
        return false;
    }
    
    if (!findQuery.next()) {
        qDebug() << "未找到匹配的命令记录，下载URL:" << downloadUrl;
        return false;
    }
    
    // 获取当前的 PARAMS JSON
    QString currentParams = findQuery.value("PARAMS").toString();
    QString commandId = findQuery.value("ID").toString();
    
    // 更新 PARAMS JSON 中的 LOCAL_FILE_PATH
    QString updatedParams = updateParamInJson(currentParams, "LOCAL_FILE_PATH", localFilePath);
    
    // 更新数据库记录
    QString lastModifyDate = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QSqlQuery updateQuery(m_database);
    updateQuery.prepare("UPDATE kms_command SET PARAMS = ?, LAST_MODIFY_DATE = ? WHERE ID = ?");
    updateQuery.addBindValue(updatedParams);
    updateQuery.addBindValue(lastModifyDate);
    updateQuery.addBindValue(commandId);
    
    if (!updateQuery.exec()) {
        qDebug() << "更新命令记录LOCAL_FILE_PATH失败:" << updateQuery.lastError().text();
        return false;
    }
    
    if (updateQuery.numRowsAffected() > 0) {
        qDebug() << "成功更新命令记录LOCAL_FILE_PATH，下载URL:" << downloadUrl << "本地路径:" << localFilePath;
        return true;
    } else {
        qDebug() << "更新命令记录失败，未影响任何行";
        return false;
    }
}

KmsCommand CommandRepository::findByLocalFilePath(const QString &localFilePath)
{
    KmsCommand command;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return command;
    }
    
    if (localFilePath.isEmpty()) {
        qDebug() << "本地文件路径为空，无法查询命令记录";
        return command;
    }
    
    QString normalizedPath = QDir::cleanPath(localFilePath);
    normalizedPath = normalizedPath.replace('\\', '/');
    
    // 使用 LIKE 查询 PARAMS JSON 中的 LOCAL_FILE_PATH
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_command WHERE PARAMS LIKE ?");
    query.addBindValue("%\"LOCAL_FILE_PATH\":\"" + normalizedPath + "\"%");
    
    if (!query.exec()) {
        qDebug() << "查询命令记录失败:" << query.lastError().text();
        return command;
    }
    
    if (query.next()) {
        command = mapFromQuery(query);
        QString foundPath = getParamFromJson(command.params, "LOCAL_FILE_PATH");
        qDebug() << "找到匹配的命令记录，ID:" << command.id << "本地路径:" << foundPath;
    } else {
        qDebug() << "未找到匹配的命令记录，本地路径:" << localFilePath;
    }
    
    return command;
}

KmsCommand CommandRepository::findByLocalFilePathAndCommand(const QString &localFilePath, const QString &command)
{
    KmsCommand result;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return result;
    }
    
    if (localFilePath.isEmpty()) {
        qDebug() << "本地文件路径为空，无法查询命令记录";
        return result;
    }
    
    if (command.isEmpty()) {
        qDebug() << "命令类型为空，无法查询命令记录";
        return result;
    }
    
    QString normalizedPath = QDir::cleanPath(localFilePath);
    normalizedPath = normalizedPath.replace('\\', '/');
    
    // 使用 LIKE 查询 PARAMS JSON 中的 LOCAL_FILE_PATH，并添加 COMMAND 和 STATUS 条件
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_command WHERE PARAMS LIKE ? AND COMMAND = ? AND STATUS = 'PENDING'");
    query.addBindValue("%\"LOCAL_FILE_PATH\":\"" + normalizedPath + "\"%");
    query.addBindValue(command);
    
    if (!query.exec()) {
        qDebug() << "查询命令记录失败:" << query.lastError().text();
        return result;
    }
    
    if (query.next()) {
        result = mapFromQuery(query);
        QString foundPath = getParamFromJson(result.params, "LOCAL_FILE_PATH");
        qDebug() << "找到匹配的命令记录，ID:" << result.id << "命令:" << result.command << "本地路径:" << foundPath;
    } else {
        qDebug() << "未找到匹配的命令记录，本地路径:" << localFilePath << "命令:" << command;
    }
    
    return result;
}

KmsCommand CommandRepository::findByDownloadUrl(const QString &downloadUrl)
{
    KmsCommand command;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return command;
    }
    
    if (downloadUrl.isEmpty()) {
        qDebug() << "下载URL为空，无法查询命令记录";
        return command;
    }
    
    // 使用 LIKE 查询 PARAMS JSON 中的 DOWNLOAD_URL
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_command WHERE PARAMS LIKE ?");
    query.addBindValue("%\"DOWNLOAD_URL\":\"" + downloadUrl + "\"%");
    
    if (!query.exec()) {
        qDebug() << "查询命令记录失败:" << query.lastError().text();
        return command;
    }
    
    if (query.next()) {
        command = mapFromQuery(query);
        qDebug() << "找到匹配的命令记录，ID:" << command.id << "下载URL:" << downloadUrl;
    } else {
        qDebug() << "未找到匹配的命令记录，下载URL:" << downloadUrl;
    }
    
    return command;
}

bool CommandRepository::removeByCommitUrl(const QString &commitUrl)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    if (commitUrl.isEmpty()) {
        qDebug() << "提交URL为空，无法删除命令记录";
        return false;
    }
    
    // 使用 LIKE 查询 PARAMS JSON 中的 COMMIT_URL
    QSqlQuery query(m_database);
    query.prepare("DELETE FROM kms_command WHERE PARAMS LIKE ?");
    query.addBindValue("%\"COMMIT_URL\":\"" + commitUrl + "\"%");
    
    if (!query.exec()) {
        qDebug() << "删除命令记录失败:" << query.lastError().text();
        return false;
    }
    
    if (query.numRowsAffected() > 0) {
        qDebug() << "成功删除命令记录，提交URL:" << commitUrl;
        return true;
    } else {
        qDebug() << "未找到匹配的命令记录，提交URL:" << commitUrl;
        return false;
    }
}

bool CommandRepository::updateStatusByCommitUrl(const QString &commitUrl, const QString &command, const QString &status)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    if (commitUrl.isEmpty()) {
        qDebug() << "提交URL为空，无法更新命令记录状态";
        return false;
    }
    
    if (command.isEmpty()) {
        qDebug() << "命令类型为空，无法更新命令记录状态";
        return false;
    }
    
    if (status.isEmpty()) {
        qDebug() << "状态值为空，无法更新命令记录状态";
        return false;
    }
    
    // 使用 LIKE 查询 PARAMS JSON 中的 COMMIT_URL，并添加 COMMAND 条件
    QString lastModifyDate = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_command SET STATUS = ?, LAST_MODIFY_DATE = ? WHERE PARAMS LIKE ? AND COMMAND = ?");
    query.addBindValue(status);
    query.addBindValue(lastModifyDate);
    query.addBindValue("%\"COMMIT_URL\":\"" + commitUrl + "\"%");
    query.addBindValue(command);
    
    if (!query.exec()) {
        qDebug() << "更新命令记录状态失败:" << query.lastError().text();
        return false;
    }
    
    if (query.numRowsAffected() > 0) {
        qDebug() << "成功更新命令记录状态，提交URL:" << commitUrl << "命令:" << command << "状态:" << status;
        return true;
    } else {
        qDebug() << "未找到匹配的命令记录，提交URL:" << commitUrl << "命令:" << command;
        return false;
    }
}

bool CommandRepository::updateStatusByDownloadUrl(const QString &downloadUrl, const QString &command, const QString &status)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    if (downloadUrl.isEmpty()) {
        qDebug() << "下载URL为空，无法更新命令记录状态";
        return false;
    }
    
    if (command.isEmpty()) {
        qDebug() << "命令类型为空，无法更新命令记录状态";
        return false;
    }
    
    if (status.isEmpty()) {
        qDebug() << "状态值为空，无法更新命令记录状态";
        return false;
    }
    
    // 使用 LIKE 查询 PARAMS JSON 中的 DOWNLOAD_URL，并添加 COMMAND 条件
    QString lastModifyDate = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_command SET STATUS = ?, LAST_MODIFY_DATE = ? WHERE PARAMS LIKE ? AND COMMAND = ?");
    query.addBindValue(status);
    query.addBindValue(lastModifyDate);
    query.addBindValue("%\"DOWNLOAD_URL\":\"" + downloadUrl + "\"%");
    query.addBindValue(command);
    
    if (!query.exec()) {
        qDebug() << "更新命令记录状态失败:" << query.lastError().text();
        return false;
    }
    
    if (query.numRowsAffected() > 0) {
        qDebug() << "成功更新命令记录状态，下载URL:" << downloadUrl << "命令:" << command << "状态:" << status;
        return true;
    } else {
        qDebug() << "未找到匹配的命令记录，下载URL:" << downloadUrl << "命令:" << command;
        return false;
    }
}

